package com.tp7567.web;

import java.io.Serializable;
import java.util.List;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.Radio;
import org.apache.wicket.markup.html.form.RadioGroup;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import com.google.common.collect.Lists;
import com.ptgutils.wicket.link.ToggleAjaxLink;
import com.tp7567.domain.AutismLevel;
import com.tp7567.domain.AutismLevelDescription;
import com.tp7567.domain.Sintoma;
import com.tp7567.service.Question;
import com.tp7567.service.TgdDiagnosticService;
import com.tp7567.web.common.BasePage;
import com.tp7567.web.common.ButtonPanel;

public class MainPage extends BasePage {
	
	private Label questionLabel;
	private Label descriptionLabel;
	private Label diagnosticLabel;
	private Question<? extends Sintoma> question;
	private ButtonPanel prevButton;
	private ButtonPanel nextButton;
	private ButtonPanel finButton;
	private WebMarkupContainer questionContainer;
	private RadioGroup<Sintoma> answersRadioGroup;
	private Form<Void> form;
	private ListView<Sintoma> answersListView;
	private WebMarkupContainer answersContainer;
	private WebMarkupContainer questionHeader;
	
	private WebMarkupContainer autismosContainer;
	
	private List<AutismLevel> autismLevels;
	private List<AutismLevel> availableAutismLevels = TgdDiagnosticService.get().getPatient().getAvailableAutismLevels();
	
	@SuppressWarnings("serial")
	public MainPage() {
		super();
		
		autismLevels = Lists.newArrayList(AutismLevel.values());
		autismLevels.remove(AutismLevel.NONE);
		
		questionContainer = new WebMarkupContainer("questionContainer");
		questionContainer.setOutputMarkupPlaceholderTag(true);
		add(questionContainer);
		
		diagnosticLabel = new Label("diagnostic");
		diagnosticLabel.setOutputMarkupPlaceholderTag(true);
		questionContainer.add(diagnosticLabel);
		
		questionHeader = new WebMarkupContainer("questionHeader");
		questionHeader.setOutputMarkupPlaceholderTag(true);
		questionContainer.add(questionHeader);
		
		questionLabel = new Label("question");
		questionHeader.add(questionLabel);
		
		descriptionLabel = new Label("description");
		questionHeader.add(descriptionLabel);
		
		form = new Form<Void>("form");
		questionContainer.add(form);
		
		answersContainer = new WebMarkupContainer("answersContainer");
		answersContainer.setOutputMarkupPlaceholderTag(true);
		form.add(answersContainer);
		
		answersRadioGroup = new RadioGroup<Sintoma>("answersRadioGroup", new Model<Sintoma>());
		answersRadioGroup.add(new AjaxFormChoiceComponentUpdatingBehavior() {
			
			@Override
			protected void onUpdate(AjaxRequestTarget target) {
				Sintoma sintoma = answersRadioGroup.getModelObject();
				question.executeAnswer(TgdDiagnosticService.get().getPatient(), sintoma);
				
				availableAutismLevels = TgdDiagnosticService.get().inverseDiagnose();
				target.addComponent(autismosContainer);
			}
		});
		answersContainer.add(answersRadioGroup);
		
		prevButton = new ButtonPanel("prev", true) {
			
			@Override
			protected void onClick(AjaxRequestTarget target) {
				
				TgdDiagnosticService.get().prevQuestion();
				loadQuestion(target);
			}
		};
		prevButton.setOutputMarkupPlaceholderTag(true);
		form.add(prevButton);
		
		nextButton = new ButtonPanel("next", true) {
			
			@Override
			protected void onClick(AjaxRequestTarget target) {
				
				TgdDiagnosticService.get().nextQuestion();
				loadQuestion(target);
			}
		};
		nextButton.setOutputMarkupPlaceholderTag(true);
		form.add(nextButton);
		
		finButton = new ButtonPanel("fin", true) {
			
			@Override
			protected void onClick(AjaxRequestTarget target) {
				
				answersContainer.setVisible(false);
				diagnosticLabel.setVisible(true);
				prevButton.setVisible(true);
				nextButton.setVisible(false);
				finButton.setVisible(false);
				questionHeader.setVisible(false);
				
				AutismLevel autismLevel = TgdDiagnosticService.get().diagnose();
				diagnosticLabel.setDefaultModel(new Model<String>("Diagnostico: " + autismLevel.getName()));
				target.addComponent(questionContainer);
			}
		};
		form.add(finButton);
		
		add(new ButtonPanel("newPatient", false) {
			
			@Override
			protected void onClick(AjaxRequestTarget target) {
				TgdDiagnosticService.get().createPatient();
				availableAutismLevels = TgdDiagnosticService.get().getPatient().getAvailableAutismLevels();
				loadQuestion(target);
				
				finButton.setVisible(true);
				diagnosticLabel.setVisible(false);
				target.addComponent(questionContainer);
				target.addComponent(autismosContainer);
			}
		});
		
		loadQuestion(null);
		
		answersListView = new ListView<Sintoma>("answersListView", new PropertyModel<List<Sintoma>>(this,
				"question.availableAnswers")) {
			
			@Override
			protected void populateItem(final ListItem<Sintoma> item) {
				
				Sintoma sintoma = item.getModelObject();
				Sintoma selectedSintoma = question.getSelectedAnswer(TgdDiagnosticService.get().getPatient());
				
				Radio<Sintoma> answerRadio = new Radio<Sintoma>("answerRadio", new Model<Sintoma>(sintoma));
				answerRadio.setMarkupId(answerRadio.getId() + item.getIndex());
				item.add(answerRadio);
				
				Label answerLabel = new Label("answerLabel", sintoma.getName());
				answerLabel.add(new SimpleAttributeModifier("for", answerRadio.getId() + item.getIndex()));
				item.add(answerLabel);
				
				if (selectedSintoma != null) {
					if (sintoma.equals(selectedSintoma)) {
						answersRadioGroup.setModelObject(sintoma);
					}
				}
			}
		};
		answersRadioGroup.add(answersListView);
		
		autismosContainer = new WebMarkupContainer("autismosContainer");
		autismosContainer.setOutputMarkupPlaceholderTag(true);
		add(autismosContainer);
		
		ListView<AutismLevel> autismosListView = new ListView<AutismLevel>("autismosListView",
				new PropertyModel<List<AutismLevel>>(this, "autismLevels")) {
			
			@SuppressWarnings({ "unchecked", "rawtypes" })
			@Override
			protected void populateItem(final ListItem<AutismLevel> item) {
				
				final AutismLevel autismLevel = item.getModelObject();
				
				final WebMarkupContainer autismoDetailsContainer = new WebMarkupContainer("autismoDetailsContainer");
				autismoDetailsContainer.setOutputMarkupId(true);
				item.add(autismoDetailsContainer);
				
				ListView<AutismLevelDescription> autismoDetailsListView = new ListView<AutismLevelDescription>(
						"autismoDetailsListView", new Model((Serializable)autismLevel.getAutismLevelDescriptions())) {
					
					@Override
					protected void populateItem(final ListItem<AutismLevelDescription> item) {
						
						AutismLevelDescription autismLevelDescription = item.getModelObject();
						
						List<Sintoma> selectedSintomas = TgdDiagnosticService.get().getPatient().getSintomas();
						boolean isChecked = autismLevelDescription.matches(selectedSintomas);
						CheckBox autismoDetailCheckBox = new CheckBox("autismoDetailCheckbox", new Model<Boolean>());
						autismoDetailCheckBox.setMarkupId(autismLevel + autismoDetailCheckBox.getId() + item.getIndex());
						autismoDetailCheckBox.setOutputMarkupPlaceholderTag(true);
						autismoDetailCheckBox.setModel(new Model<Boolean>(isChecked));
						autismoDetailCheckBox.setEnabled(false);
						item.add(autismoDetailCheckBox);
						
						Label autismoDetailLabel = new Label("autismoDetailLabel", autismLevelDescription.getType()
								+ ": " + autismLevelDescription.toString());
						autismoDetailLabel.add(new SimpleAttributeModifier("for", autismoDetailCheckBox.getMarkupId()));
						item.add(autismoDetailLabel);
					}
				};
				autismoDetailsContainer.add(autismoDetailsListView);
				
				final ToggleAjaxLink moduleLink = new ToggleAjaxLink("autismoLabelLink", autismoDetailsContainer, false) {
					
					@Override
					public void onClick(AjaxRequestTarget target) {
						super.onClick(target);
					}
				};
				moduleLink.setOutputMarkupId(true);
				item.add(moduleLink);
				
				boolean isAvailable = availableAutismLevels.contains(autismLevel);
				Label autismoLabel = new Label("autismoLabel", autismLevel.getName());
				autismoLabel.add(new SimpleAttributeModifier("class", isAvailable ? "autismoLabel"
						: "notAvailableAutismoLabel"));
				moduleLink.add(autismoLabel);
			}
		};
		autismosContainer.add(autismosListView);
	}
	
	private void loadQuestion(AjaxRequestTarget target) {
		question = TgdDiagnosticService.get().getCurrentQuestion();
		questionLabel.setDefaultModel(new Model<String>(question.getQuestionName()));
		descriptionLabel.setDefaultModel(new Model<String>(question.getDescription()));
		answersContainer.setVisible(true);
		questionHeader.setVisible(true);
		diagnosticLabel.setVisible(false);
		
		finButton.setVisible(true);
		prevButton.setVisible(TgdDiagnosticService.get().hasPrevQuestion());
		nextButton.setVisible(TgdDiagnosticService.get().hasNextQuestion());
		if (target != null) {
			target.addComponent(questionContainer);
		}
	}
}
